package com.xbongbong.saas.model.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.pojo.dto.DeleteDTO;
import com.xbongbong.paas.elasticsearch.pojo.dto.InsertDTO;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.SaasParticularAttributePoJo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.DataUtil;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.errorcodes.WorkReportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formdata.pojo.SaasSpecialParamPojo;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.user.pojo.ReturnUserAndDepartmentPojo;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.dao.WorkReportDao;
import com.xbongbong.saas.domain.entity.WorkPlanEntity;
import com.xbongbong.saas.domain.entity.ext.WorkReportEntityExt;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.business.WorkReportFieldEnum;
import com.xbongbong.saas.enums.business.WorkReportPlanEnum;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.model.PaasFormSubDataModel;
import com.xbongbong.saas.model.WorkPlanModel;
import com.xbongbong.saas.model.WorkReportModel;
import com.xbongbong.saas.model.WorkReportSubDataModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerFromFormData;

/**
 * @author long.rao
 * @version v1.0
 * @date 2019/1/24 21:40
 * @since v1.0
 */
@Service("workReportModel")
public class WorkReportModelImpl implements WorkReportModel {

    @Resource
    private WorkPlanModel workPlanModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private WorkReportDao workReportDao;
    @Resource
    private PaasFormSubDataModel paasFormSubDataModel;
    @Resource
    private WorkReportSubDataModel workReportSubDataModel;

    @Override
    public Integer insert(WorkReportEntityExt entity) throws XbbException {
        //TODO  先进行数据库的插入动作
        long now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        // 30662 【app-工作报告】开启严控模式后，点击详情页编辑按钮，未展示流水号
        // entity.setSerialNo("");
        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        workReportDao.insert(entity);
        PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
        BeanUtil.copyProperties(entity, paasFormDataEntity);
        InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_WORK_REPORT);
        paasEsModel.insert(insertDTO);
        paasFormSubDataModel.insertSubFormData(entity, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        return null;
    }

    @Override
    //@Async(value = "addUpdateDelThreadPool")
    public Integer update(WorkReportEntityExt entity) throws XbbException {
        long now = DateUtil.getInt();
        entity.setUpdateTime(now);
        paasFormSubDataModel.transferSubForm(entity, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        Integer success = workReportDao.update(entity);
        PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
        BeanUtil.copyProperties(entity, paasFormDataEntity, false);
        InsertDTO insertDTO = paasEsModel.getSaveDTO(paasFormDataEntity, IndexTypeEnum.IDX_SAAS_WORK_REPORT);
        paasEsModel.update(insertDTO);
        paasFormSubDataModel.updateSubFormData(entity, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        if (Objects.nonNull(entity.getSubFormData()) && !entity.getSubFormData().isEmpty()) {
            entity.getData().putAll(entity.getSubFormData());
        }
        return success;
    }

    @Override
    public List<WorkReportEntityExt> findEntitys(Map<String, Object> param) {
        List<WorkReportEntityExt> entitys = workReportDao.findEntitys(param);
        Object corpid = param.get(ParameterConstant.CORPID);
        if (Objects.nonNull(corpid)) {
            paasFormSubDataModel.findSubEntity(corpid.toString(), entitys, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        }
        return entitys;
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return workReportDao.getEntitysCount(param);
    }

    @Override
    public WorkReportEntityExt getByKey(Long key, String corpid) {
        WorkReportEntityExt entityExt = workReportDao.getByKey(key, corpid);
        paasFormSubDataModel.findSubEntity(corpid, Collections.singletonList(entityExt), IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        return entityExt;
    }

    @Override
    public List<WorkReportEntityExt> getWorkReport(String corpid, String userId, String workReportDate, String type) {
        List<WorkReportEntityExt> entityExts = workReportDao.getWorkReport(corpid, userId, workReportDate, type);
        paasFormSubDataModel.findSubEntity(corpid, entityExts, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        return entityExts;
    }

    @Override
    public Integer deleteBatch(List<Long> list, String corpid) throws XbbException {
        Integer integer = workReportDao.deleteBatch(list, corpid);
        paasEsModel.deleteBatch(list, corpid, DelEnum.DELETE.getDel(), IndexTypeEnum.IDX_SAAS_WORK_REPORT);
        paasFormSubDataModel.deleteBatchByDataId(list, corpid, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB, DelEnum.DELETE_SUBFORM);
        return integer;
    }
    @Override
    public Integer updateBatch(List<UpdateDataEntity> updateList, String corpid) throws XbbException {
        //1. 先拿到子表单数据
        List<UpdateDataEntity> subList = DataUtil.getUpdateSubDataList(updateList);
        // 2. 主表删掉子表单数据
        DataUtil.removeSubDataInData(updateList);
        Integer integer = 0;
        if (CollectionsUtil.isNotEmpty(updateList)) {
            integer = workReportDao.updateBatch(updateList, corpid);
            paasEsModel.updateBatchMuchField(updateList, IndexTypeEnum.IDX_SAAS_WORK_REPORT);
        }
        if (!subList.isEmpty()) {
            workReportSubDataModel.updateBatch(subList, corpid);
        }
        return integer;
    }

    @Override
    public Integer deleteByKey(Long key,String corpid) throws XbbException{
        DeleteDTO deleteDTO = new DeleteDTO();
        deleteDTO.setEsId(corpid+"_"+key);
        deleteDTO.setIndexTypeEnum(IndexTypeEnum.IDX_SAAS_WORK_REPORT);
        paasEsModel.delete(deleteDTO);
        Integer integer = workReportDao.deleteByKey(key, corpid);
        paasFormSubDataModel.deleteByDataId(key, corpid, IndexTypeEnum.IDX_SAAS_WORK_REPORT_SUB);
        return integer;
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return workReportDao.findEntitys(param);
    }

    @Override
    public void formatUpdateExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        String corpid = formatExplainDTO.getCorpid();
        // 创建人
        String creatorId = formatExplainDTO.getDataEntity().getCreatorId();
        // 保证数据正确，取data里的类型再转为subBusinessType
        Integer type = getIntegerFromFormData(formatExplainDTO.getDataEntity().getData(), WorkReportFieldEnum.TYPE.getAttr());
        WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByType(type);
        if (workReportTypeEnum == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002, SystemErrorCodeEnum.API_ERROR_100002.getMsg());
        }
        Integer subBusinessType = workReportTypeEnum.getBusinessType();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(subBusinessType);
        SaasSpecialParamPojo saasSpecialParamPojo = formatExplainDTO.getSaasSpecialParamPojo();
        Boolean flag = false;
        if (saasSpecialParamPojo != null && !(Objects.equals(saasSpecialParamPojo.getReportStartDate(), null))) {
            flag = true;
        }
        Integer workReportDate = getIntegerFromFormData(formatExplainDTO.getDataEntity().getData(), WorkReportFieldEnum.REPORT_DATE.getAttr());

        if (Objects.isNull(workReportDate)) {
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207015);
        }
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, WorkReportFieldEnum.THIS_PLAN.getAttr())) {
                List<WorkPlanEntity> thisPlans = getThisPlansByTime(corpid, creatorId, type, workReportDate);
                SaasParticularAttributePoJo saasParticularAttributePoJo = Objects.isNull(fieldAttrEntity.getSaasParticularAttributePoJo())
                        ? new SaasParticularAttributePoJo() : fieldAttrEntity.getSaasParticularAttributePoJo();
                JSONArray array = new JSONArray();
                for (WorkPlanEntity entity : thisPlans) {
                    JSONObject obj = new JSONObject();
                    obj.put(WorkReportPlanEnum.ID.getAttr(), entity.getId());
                    obj.put(WorkReportPlanEnum.CONTENT.getAttr(), entity.getContent());
                    obj.put(WorkReportPlanEnum.STATUS.getAttr(), entity.getStatus());
                    array.add(obj);
                }
                saasParticularAttributePoJo.setInitialValue(array);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
            } else if (Objects.equals(attr, WorkReportFieldEnum.NEXT_PLAN.getAttr())) {
                Long dataId = formatExplainDTO.getDataEntity().getId();
                List<WorkPlanEntity> workPlanEntities = getNextPlansByTime(corpid, creatorId, type, dataId);
                SaasParticularAttributePoJo saasParticularAttributePoJo = Objects.isNull(fieldAttrEntity.getSaasParticularAttributePoJo())
                        ? new SaasParticularAttributePoJo() : fieldAttrEntity.getSaasParticularAttributePoJo();
                JSONArray array = new JSONArray();
                for (WorkPlanEntity entity : workPlanEntities) {
                    JSONObject obj = new JSONObject();
                    obj.put(WorkReportPlanEnum.ID.getAttr(), entity.getId());
                    obj.put(WorkReportPlanEnum.CONTENT.getAttr(), entity.getContent());
                    array.add(obj);
                }
                saasParticularAttributePoJo.setInitialValue(array);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);

            } else if (Objects.equals(attr, WorkReportFieldEnum.TYPE.getAttr())) {
                List<ItemPoJo> itemPoJos = fieldAttrEntity.getItems();
                ItemPoJo itemPoJo = new ItemPoJo();
                switch (redundantTemplateTypeEnum) {
                    case WORKREPORT_DAILY:
                        itemPoJo = itemPoJos.get(0);
                        itemPoJo.setChecked(true);
                        itemPoJo.setText(WorkReportTypeEnum.DAILY.getName());
                        itemPoJo.setValue(WorkReportTypeEnum.DAILY.getType().toString());
                        break;
                    case WORKREPORT_WEEKLY:
                        itemPoJo = itemPoJos.get(1);
                        itemPoJo.setChecked(true);
                        itemPoJo.setText(WorkReportTypeEnum.WEEKLY.getName());
                        itemPoJo.setValue(WorkReportTypeEnum.WEEKLY.getType().toString());
                        break;
                    case WORKREPORT_MONTHLY:
                        itemPoJo = itemPoJos.get(2);
                        itemPoJo.setChecked(true);
                        itemPoJo.setText(WorkReportTypeEnum.MONTHLY.getName());
                        itemPoJo.setValue(WorkReportTypeEnum.MONTHLY.getType().toString());
                        break;
                    default:
                        break;
                }
            } else if (Objects.equals(attr, WorkReportFieldEnum.REPORT_DATE.getAttr())) {
                SaasParticularAttributePoJo saasParticularAttributePoJo = fieldAttrEntity.getSaasParticularAttributePoJo();
                saasParticularAttributePoJo = saasParticularAttributePoJo == null ? new SaasParticularAttributePoJo() : saasParticularAttributePoJo;
                DefaultAttrPoJo defaultAttrPoJo = fieldAttrEntity.getDefaultAttr();
                defaultAttrPoJo.setDefaultType("dateByBackEnd");
                defaultAttrPoJo.setDefaultValue(workReportDate + "");
                saasParticularAttributePoJo.setDateLimit((long) (DateUtil.getTodayInt() + TimeConstant.SECONDS_PER_DAY));
                saasParticularAttributePoJo.setLimitType(true);
                fieldAttrEntity.setSaasParticularAttributePoJo(saasParticularAttributePoJo);
                // 从编辑按钮编辑工作报告，报告日期不能编辑 fromEdit为1代表从编辑按钮进入编辑
                if (saasSpecialParamPojo != null && saasSpecialParamPojo.getFromEdit() != null && Objects.equals(saasSpecialParamPojo.getFromEdit(), 1)) {
                    fieldAttrEntity.setEditable(0);
                }
            }

        }
    }

    /**
     * 获取今日/本周/本月计划
     *
     * @param corpid    公司id
     * @param userId    员工id
     * @param type  日报类型
     * @return java.util.List<com.xbongbong.saas.domain.entity.WorkPlanEntity>
     * @author feng.zheng
     * @date 2019/2/13 11:00
     */
    @Override
    public List<WorkPlanEntity> getThisPlansByTime(String corpid, String userId, Integer type, Integer reportDate) {

        if (userId == null) {
            return new ArrayList<>();
        }
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        Integer planDate;
        WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByType(type);
        if (Objects.isNull(workReportTypeEnum)) {
            workReportTypeEnum = WorkReportTypeEnum.DAILY;
            type = workReportTypeEnum.getType();
        }
        switch (workReportTypeEnum) {
            case DAILY:
                planDate = DateUtil.getTodayInt(reportDate);
                params.put("planDate", planDate);
                break;
            case WEEKLY:
                planDate = DateUtil.getWeekMorningInSomeday(reportDate);
                params.put("planDate", planDate);
                break;
            case MONTHLY:
                params.put("planDate", DateUtil.getFirstDateOfMonthInSomeday(reportDate));
                break;
            default:
                planDate = DateUtil.getTodayInt(reportDate);
                params.put("planDate", planDate);
                type = WorkReportTypeEnum.DAILY.getType();
                break;
        }

        params.put("type", type);
        params.put("corpid", corpid);
        params.put("userId", userId);
        params.put("del", 0);

        List<WorkPlanEntity> thisPlans = workPlanModel.findEntitys(params);
        if (thisPlans == null) {
            thisPlans = new ArrayList<>();
        }
        return thisPlans;
    }

    /**
     * 获取明日/下周/下月计划
     *
     * @param corpid    公司id
     * @param userId    员工id
     * @param type   报告类型
     * @param id 报告id
     * @return java.util.List<com.xbongbong.saas.domain.entity.WorkPlanEntity>
     * @author feng.zheng
     * @date 2019/2/13 11:00
     */
    @Override
    public List<WorkPlanEntity> getNextPlansByTime(String corpid, String userId, Integer type, Long id) {
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type", type);
        params.put("corpid", corpid);
        params.put("userId", userId);
        params.put("reportId", id);
        params.put("del", 0);

        List<WorkPlanEntity> thisPlans = workPlanModel.findEntitys(params);
        if (thisPlans == null) {
            thisPlans = new ArrayList<>();
        }
        return thisPlans;
    }

    @Override
    public void formatData(SaasAnalysisDataDTO saasAnalysisDataDTO, JSONObject result) throws XbbException {
        Integer type = result.getInteger(WorkReportFieldEnum.TYPE.getAttr());
        result.put(WorkReportFieldEnum.TYPE.getAttr(), type.toString());
        Long id = saasAnalysisDataDTO.getDataId();
        // 25484 【紧急】【app-工作报告】编辑日/周/月报告时，今日/周/月计划值显示为空
        String creatorId = "";
        if (Objects.nonNull(result.get(WorkReportFieldEnum.CREATOR_ID.getAttr())) && StringUtil.isNotEmpty(result.getString(WorkReportFieldEnum.CREATOR_ID.getAttr()))) {
            if (result.get(WorkReportFieldEnum.CREATOR_ID.getAttr()) instanceof ReturnUserAndDepartmentPojo) {
                ReturnUserAndDepartmentPojo returnUserAndDepartmentPojo = result.getJSONObject(WorkReportFieldEnum.CREATOR_ID.getAttr()).toJavaObject(ReturnUserAndDepartmentPojo.class);
                creatorId = returnUserAndDepartmentPojo.getId().toString();
            }else {
                result.getString(WorkReportFieldEnum.CREATOR_ID.getAttr());
            }
        } else {
            if (Objects.nonNull(id) && id > 0L) {
                WorkReportEntityExt entityExt = getByKey(id, saasAnalysisDataDTO.getCorpid());
                creatorId = entityExt.getCreatorId();
            } else {
                creatorId = saasAnalysisDataDTO.getUserId();
            }
        }
        // 数据为空时再重新获取明日计划
        if (result.containsKey(WorkReportFieldEnum.NEXT_PLAN.getAttr()) && result.getJSONArray(WorkReportFieldEnum.NEXT_PLAN.getAttr()).isEmpty()) {
            List<WorkPlanEntity> workPlanEntities = getNextPlansByTime(saasAnalysisDataDTO.getCorpid(), creatorId, type, id);
            JSONArray nextPlans = new JSONArray();
            for (WorkPlanEntity entity : workPlanEntities) {
                JSONObject object = new JSONObject();
                object.put(WorkReportPlanEnum.CONTENT.getAttr(), entity.getContent());
                object.put(WorkReportPlanEnum.ID.getAttr(), entity.getId());
                nextPlans.add(object);
            }
            result.put(WorkReportFieldEnum.NEXT_PLAN.getAttr(), nextPlans);
        }

        List<WorkPlanEntity> thisPlans = getThisPlansByTime(saasAnalysisDataDTO.getCorpid(), creatorId, type, result.getInteger(WorkReportFieldEnum.REPORT_DATE.getAttr()));
        JSONArray thisPlan = new JSONArray();
        for (WorkPlanEntity entity : thisPlans) {
            JSONObject object = new JSONObject();
            object.put(WorkReportPlanEnum.CONTENT.getAttr(), entity.getContent());
            object.put(WorkReportPlanEnum.STATUS.getAttr(), entity.getStatus());
            object.put(WorkReportPlanEnum.ID.getAttr(), entity.getId());
            thisPlan.add(object);
        }

        result.put(WorkReportFieldEnum.THIS_PLAN.getAttr(), thisPlan);
    }
}
